<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    img {
      width: 100%;
      height: 100%;
      display: block;
    }

    .box {
      width: 450px;

      margin: 50px;
      display: flex;
      flex-direction: column;

      position: relative;
    }

    .box>.show {
      width: 400px;
      height: 400px;
      border: 1px solid #333;
      position: relative;
    }

    .box>.show>.mask {
      width: 200px;
      height: 200px;
      background-color: yellow;
      opacity: .4;
      position: absolute;
      top: 0px;
      left: 0px;
      display: none;
    }

    .box>.list {
      width: 100%;
      flex: 1;

      display: flex;
      justify-content: flex-start;
      align-items: center;

      box-sizing: border-box;
      padding: 20px;
    }

    .box>.list>p {
      width: 54px;
      height: 54px;
      border: 1px solid #333;
      margin-right: 10px;
    }

    .box>.list>p.active {
      border-color: red;
    }

    .box>.enlarge {
      width: 400px;
      height: 400px;
      position: absolute;
      top: 0;
      left: 101%;
      background-image: url(./images/images/1.big.jpg);
      background-repeat: no-repeat;
      background-size: 800px 800px;
      background-position: 0 0;
      display: none;
    }
  </style>
</head>

<body>

  <div class="box">
    <div class="show">
      <img src="./images/images/1.jpg" alt="">
      <div class="mask"></div>
    </div>
    <div class="list">
      <p class="active">
        <img src="./images/images/1.small.jpg" showImg="./images/images/1.jpg" enlargeImg="./images/images/1.big.jpg" alt="">
      </p>
      <p>
        <img src="./images/images/2.small.jpg" showImg="./images/images/2.jpg" enlargeImg="./images/images/2.big.jpg" alt="">
      </p>
    </div>
    <div class="enlarge"></div>
  </div>
  <script>
    /* 
    分析需求：1、鼠标移入 遮罩层和 放大图都需要显示，鼠标移除的时候 遮罩层和放大图隐藏
             2、鼠标在移动的时候遮罩层要跟着鼠标动 （鼠标的中间动）（边界问题）
             3、放大图也要按照左边比例来移动
             4、鼠标移到小图上可以切换图片
     */
    class Enlarge{
      constructor(containerEle){
        this.containerEle = containerEle ;    //将容器元素变成该类的属性
        this.showEle = this.containerEle.querySelector(".show");  //获取这个容器中className为show的元素
        this.showImgEle = this.containerEle.querySelector(".show img");//获取这个容器中className为show下面的img元素
        this.maskEle = this.containerEle.querySelector(".mask");  //获取这个容器中className为mask的元素
        this.listEles = this.containerEle.querySelectorAll(".list > p");  //获取这个容器中所有的className为list下面的p标签
        this.enlargeEle = this.containerEle.querySelector(".enlarge");  //获取在这个容器中className为enlarge的元素
        this.w = this.containerEle.offsetLeft ;   //获取容器距离浏览器左边的距离
        this.h = this.containerEle.offsetTop ;  //获取容器距离浏览器上边的距离
        this.move();    //调用类中的move方法
        this.tab();     //调用类中的tab方法
      }
      tab(){
        const _that = this ;                    //申明一个常量_that保存this此时指向的实例化对象
        _that.listEles.forEach((listEle,key)=>{        //循环下面选项卡中的所有p标签元素  
          listEle.onclick = function (){        //点击其中p标签元素
            _that.listEles.forEach((item,index)=>{  //循环下面选项卡中的所有p标签元素
              item.classList.remove("active");    //移除所有p标签元素的className名为active
            });
            this.classList.add("active");     //给点击中p标签元素增加className名为active
            _that.enlargeEle.style.backgroundImage = `url(./images/images/${key+1}.big.jpg)` ;    //放大镜的背景图该成对应p标签中小图对应的大图
            _that.showImgEle.src = `./images/images/${key+1}.jpg` ;     //显示show的图改为p标签小图对应显示的图
          }
        });
      }
      move(){
        const _that = this ;                       //申明一个常量_that保存this此时指向的实例化对象
        this.showEle.onmouseenter = function (){    //鼠标移进show元素时
          _that.maskEle.style.display = "block" ;     //遮罩显示
          _that.enlargeEle.style.display = "block" ;  //背景显示
        }
        this.showEle.onmouseleave = function (){      //鼠标移出show元素时
          _that.maskEle.style.display = "none" ;      //遮罩隐藏
          _that.enlargeEle.style.display = "none" ;   //背景隐藏
        }
        this.showEle.onmousemove = function (event){    //鼠标移动时
          let e = event || window.event ;               //事件兼容
          _that.maskWidth = _that.maskEle.offsetWidth ;   //获取mask元素的宽
          _that.maskHeight = _that.maskEle.offsetHeight ;  //获取mask元素的高
          let mouseX = e.clientX ;                //获取鼠标距离浏览器左边框距离
          let mouseY = e.clientY ;                //获取鼠标距离浏览器上边框距离
          let x = mouseX - _that.w - _that.maskWidth/2 ;  
          let y = mouseY - _that.h - _that.maskHeight/2 ; 
          if( x < 0 ){
            x = 0 ;
          }
          if( x > _that.showEle.offsetWidth - _that.maskWidth ){
            x = _that.showEle.offsetWidth - _that.maskWidth ; 
          }
          if( y < 0 ){
            y = 0 ; 
          }
          if( y > _that.showEle.offsetHeight - _that.maskHeight ){
            y = _that.showEle.offsetHeight - _that.maskHeight  ;
          }
          _that.maskEle.style.left = x + "px" ; 
          _that.maskEle.style.top = y + "px" ; 
          let arr = (getComputedStyle(_that.enlargeEle,"null")["background-size"]).split(" ") ; //获取放大镜背景的图片大小，  800px 800px，空格切割
          let xx = parseInt(arr[0]) * x / _that.showEle.offsetWidth ;       //计算比值
          let yy = parseInt(arr[1]) * y / _that.showEle.offsetHeight ;      //计算比值
          _that.enlargeEle.style.backgroundPosition = `-${xx}px -${yy}px` ; 
        }
      }
    }
    let boxEle = document.querySelector(".box");
    console.log(boxEle);
    new Enlarge(boxEle);
  </script>


</body>

</html>